import unittest
from basic_module import *

class TableTest(unittest.TestCase):
    def testInstanciation(self):
        t = Table(3,3)
        assert len(t.board) == 3
        t = Table(3,0)
        assert len(t.board) == 3
        
        try:
            t = Table()
            return False
        except:
            return True

    def testGet(self):
                t = Table(10,10)
                assert isinstance(t.get(0,0), Ground)
                try:
                        t.get(10,10)
                        return False
                except:
                        return True

    def testPut(self):
            t = Table(5,5)
            p = MobilePiece('scout',2,'allied')
            assert t.get(0,1).get_name() == 'Ground'
            t.put(p,0,1)
            assert t.get(0,1).get_name() == 'scout'
            try:
                    t.put(p,5,5)
                    return False
            except:
                    return True

            

    def testRemove(self):
            t = Table(10,10)
            p = MobilePiece('scout',2,'allied')
            t.put(p,0,1)
            assert t.get(0,1).get_name() == 'scout'
            t.remove(0,1)
            assert t.get(0,1).get_name() == 'Ground'

    def testIs_clean(self):
            t = Table(10,10)
            assert t.is_clean(0,0)
            p = MobilePiece('scout',2,'allied')
            t.put(p,0,0)
            assert not t.is_clean(0,0)
            
    def testClear(self):
            t = Table(10,10)
            p = MobilePiece('scout',2,'allied')
            t.put(p,0,0)
            assert not t.is_clean(0,0)
            t.clear(0,0)
            assert t.is_clean(0,0)
        
class GroundTest(unittest.TestCase):
    def testInstanciation(self):
        g = Ground()
        assert isinstance(g, Ground)
        assert g.get_name() == 'Ground'

class WaterTest(unittest.TestCase):
    def testInstanciation(self):
        w = Water()
        assert isinstance(w, Water)
        assert w.get_name() == 'Water'
 
class PieceTest(unittest.TestCase):
    def testInstanciation(self):
        p = Piece('scout','allied')
        assert isinstance(p, Piece)
        try:
            p = Piece('scout')
            return False
        except:
            return True
        p = Piece(None,'allied')
    
    def testGet_owner(self): 
        p = Piece('marshal','allied')
        assert p.get_owner() == 'allied'
        p = Piece('marshal', None)        
        assert p.get_owner() == None
    
    def testGet_name(self):
        p = Piece('marshal','allied')
        assert p.get_name() == 'marshal'
        p = Piece(None,'allied')        
        assert p.get_name() == None
        
class MobilePieceTest(unittest.TestCase):
    def testIsntanciation(self):
        mp = MobilePiece('scout',2, 'allied')
        assert mp.value == 2
        try:
            mp = MobilePiece('scout', 'allied')
            return False
        except:
            return True
    
    def test__cmp__(self):
        mp =  MobilePiece('scout',2, 'allied')
        other_mp = MobilePiece('miner', 3, 'allied')
        assert mp < other_mp
        mp =  MobilePiece('scout',2, 'allied')
        other_mp = MobilePiece('miner', 2, 'allied')
        assert not mp < other_mp
        assert mp != None
        
    def testGet_value(self):
        mp = MobilePiece('miner', 3, 'allied')
        assert mp.get_value() == 3

        try:
            mp = MobilePiece('miner', None, 'allied')        
            return False
        except:
            return True
        
        try:
            mp = MobilePiece('miner')        
            return False
        except:
            return True

class ImmovablePieceTest(unittest.TestCase):
    def testIsntanciation(self):
        ip = ImmovablePiece('bomb', 'allied')
        assert ip.name == 'bomb'
        assert ip.owner == 'allied'
        try:
            ip = ImmovablePiece('bomb')
            return False
        except:
            return True    
        
        try:
            ip = ImmovablePiece(None, 'allied')
            return False
        except:
            return True

class ArmyTest(unittest.TestCase):
        def testInstanciation(self):
                a = Army('allied')
                assert a.owner == 'allied'
                assert a.name == 'Allied Army'
                assert len(a.pieces) == 12
                assert a.length == 40
                try:
                        a = Army()
                        return False
                except:
                        return True

        def testGet_owner(self):
                a = Army('allied')
                assert a.get_owner() == 'allied'
                
        def testGet_name(self):
                a = Army('allied')
                assert a.get_name() == 'Allied Army'
                a = Army('enemy')
                assert a.get_name() == 'Allied Army'
                a = Army('')
                assert a.get_name() == 'Allied Army'

        def testAdd_piece(self):
                a = Army('allied')
                p = Piece('scout','allied')
                a.add_piece(p)
                assert a.length == 41
                print len(a.pieces) == 12

        def testGet_piece(self):
                a = Army('allied')
                print a.get_piece('scout').get_value()

        def testRemove_piece(self):
                a = Army('allied')
                assert a.length == 40
                a.remove_piece('scout')
                assert a.length == 39
                assert isinstance((a.remove_piece('spy')),MobilePiece)
                assert a.length == 38
                a.remove_piece('qualquer coisa')
                assert a.length == 38

                
        def testCount(self):
                a = Army('allied')
                assert a.count('marshal') == 1
                a.remove_piece('marshal')
                assert a.count('marshal') == 0
                assert a.count('qualquer coisa') == 0

        def testLen(self):
                a = Army('a')
                assert len(a) == 40
                
class ShadowArmyTest(unittest.TestCase):
    def testInstanciation(self):
        sa = ShadowArmy()
        assert sa.name == 'Shadow Army'
        assert sa.owner == 'Enemy'
        sa = ShadowArmy('allied')
        assert sa.name == 'Shadow Army'
        assert sa.owner == 'allied'
        assert len(sa.shadow_army) == 40
        
    def testGet_name(self):
        sa = ShadowArmy()
        assert sa.get_name() == 'Shadow Army'
        
    def testGet_owner(self):
        sa = ShadowArmy()
        assert sa.get_owner() == 'Enemy'
        
class CombatGameTest(unittest.TestCase):
    def testInstanciation(self):
        cg = CombatGame()
        assert len(cg.table.board) == 10
        assert cg.army.get_owner() == 'Allied'
        assert isinstance(cg.table.get(4,3), Water)  
        assert isinstance(cg.table.get(6,3), Ground)
        assert cg.status == cg.POPULATING
        assert len(cg.allied_graveyard) == 0
        cg.allied_graveyard.append(1)
        assert not len(cg.allied_graveyard) == 0

    def testChange_status(self):
                cg = CombatGame()
                assert cg.status == cg.POPULATING
                cg.change_status(cg.ATTACK)
                assert cg.status == cg.ATTACK
                try:
                        cg.change_status(cg.QQ_COISA)
                        return False
                except:
                        return True

    def testAdd_piece(self):
                cg = CombatGame()
                cg.add_piece('piece',0,0)
                assert not cg.table.is_clean(0,0)
                cg.change_status(cg.BATTLE)
                assert cg.table.is_clean(0,1)
                cg.add_piece('piece',0,1)
                assert cg.table.is_clean(0,1)
                
    def testChange_pieces(self):
                cg = CombatGame()
                assert cg.status == cg.POPULATING
                cg.add_piece('scout',0,0)
                assert isinstance(cg.table.get(0,0), MobilePiece)
                cg.add_piece('spy',0,4)
                cg.change_pieces(0,0,0,4)
                assert cg.table.get(0,0).get_name() == 'spy'
                assert cg.table.get(0,4).get_name() == 'scout'    
                cg.change_status(cg.BATTLE)
                cg.change_pieces(0,0,0,3)
                assert cg.table.get(0,0).get_name() == 'spy'

    def testPopulate_with_shadows(self):
                cg = CombatGame()
                assert cg.table.get(8,8).get_name() == 'Ground'
                cg.populate_with_shadows()
                assert cg.table.get(8,8).get_name() == 'Shadow'

    def testChange_shadow(self):
                cg = CombatGame()
                other_piece = Piece('marshal', 'enemy')
                assert cg.table.get(7,7).get_name() == 'Ground'
                cg.populate_with_shadows()
                assert cg.table.get(7,7).get_name() == 'Shadow'
                cg.change_status(cg.ATTACK)
                cg.change_shadow(7,7, other_piece)
                assert cg.table.get(7,7).get_name() == 'marshal'

    def testMove(self):
                cg = CombatGame()
                cg.add_piece('marshal', 0,0)
                cg.add_piece('scout', 1,0)
                cg.add_piece('bomb', 0,9)
                cg.move(0,0,0,1)
                assert not cg.table.get(0,1).get_name() == 'marshal'
                cg.change_status(cg.BATTLE)
                cg.move(0,0,0,1)
                assert cg.table.get(0,1).get_name() == 'marshal'
                cg.move(1,0,0,2)
                assert not cg.table.get(0,2).get_name() == 'scout'
                cg.move(1,0,1,6)
                assert cg.table.get(1,6).get_name() == 'scout'
                cg.move(1,6,10,6)
                assert cg.table.get(1,6).get_name() == 'scout'
                assert cg.table.get(0,9).get_name() == 'bomb'
                cg.move(0,9,1,9)
                assert cg.table.get(0,9).get_name() == 'bomb'
                
                # The Scout hadn't done a valided

    def testAtack_to(self):
                cg = CombatGame()
                cg.add_piece('marshal', 3,0)
                real_piece = MobilePiece('scout',2,'Enemy')
                cg.populate_with_shadows()
                assert cg.table.get(6,0).get_name() == 'Shadow'
                cg.change_status(cg.BATTLE)
                cg.move(3,0,4,0)
                cg.move(6,0,5,0)
                assert cg.table.get(5,0).get_name() == 'Shadow'
                cg.change_status(cg.ATTACK)
                cg.attack_to(4,0,5,0, real_piece)
                assert len(cg.enemy_graveyard) == 1
                assert len(cg.allied_graveyard) == 0 
                assert cg.table.get(5,0).get_name() == 'marshal'
                
                cg = CombatGame()
                cg.add_piece('scout', 3,0)
                real_piece = MobilePiece('marshal',10,'Enemy')
                cg.populate_with_shadows()
                assert cg.table.get(6,0).get_name() == 'Shadow'
                cg.change_status(cg.BATTLE)
                cg.move(3,0,4,0)
                cg.move(6,0,5,0)
                assert cg.table.get(5,0).get_name() == 'Shadow'
                cg.change_status(cg.ATTACK)
                cg.attack_to(4,0,5,0, real_piece)
                assert len(cg.enemy_graveyard) == 0
                assert len(cg.allied_graveyard) == 1 
                assert cg.table.get(5,0).get_name() == 'marshal'
                
                cg = CombatGame()
                cg.add_piece('scout', 3,0)
                real_piece = ImmovablePiece('bomb','Enemy')
                cg.populate_with_shadows()
                assert cg.table.get(6,0).get_name() == 'Shadow'
                cg.change_status(cg.BATTLE)
                cg.move(3,0,5,0)
                cg.change_status(cg.ATTACK)
                cg.attack_to(5,0,6,0, real_piece)
                assert len(cg.enemy_graveyard) == 1
                assert len(cg.allied_graveyard) == 1 
                assert cg.table.get(5,0).get_name() == 'Ground'
                assert cg.table.get(6,0).get_name() == 'Ground'

                cg = CombatGame()
                cg.add_piece('miner', 3,0)
                real_piece = ImmovablePiece('bomb','Enemy')
                cg.populate_with_shadows()
                assert cg.table.get(6,0).get_name() == 'Shadow'
                cg.change_status(cg.BATTLE)
                cg.move(3,0,4,0)
                cg.move(4,0,5,0)
                cg.change_status(cg.ATTACK)
                cg.attack_to(5,0,6,0, real_piece)
                assert len(cg.enemy_graveyard) == 1
                assert len(cg.allied_graveyard) == 0 
                assert cg.table.get(5,0).get_name() == 'Ground'
                assert cg.table.get(6,0).get_name() == 'miner'

                
if __name__ == '__main__':
    unittest.main()
